Keep a reference to the GdkCursor and add a private getter for it, so that
authorMatthias Clasen <mclasen@redhat.com>
Wed, 15 Jun 2005 18:37:18 +0000 (18:37 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Wed, 15 Jun 2005 18:37:18 +0000 (18:37 +0000)
2005-06-15  Matthias Clasen  <mclasen@redhat.com>

* gdk/x11/gdkwindow-x11.[hc]: Keep a reference to the
GdkCursor and add a private getter for it, so that we can
update the cursor when the cursor theme changes.

* gdk/gdk.symbols:
* gdk/x11/gdkx.h:
* gdk/x11/gdkcursor-x11.c (gdk_x11_display_set_cursor_theme):
New function to change the cursor theme.

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-8
docs/reference/gdk/gdk-sections.txt
gdk/gdk.symbols
gdk/x11/gdkcursor-x11.c
gdk/x11/gdkwindow-x11.c
gdk/x11/gdkwindow-x11.h
gdk/x11/gdkx.h

index 5ffaa3982526053323e54cbe201a08d42f17d2fd..9fd51f2302d8f3db4b7e1ccc35c54e165dd9b9dd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2005-06-15  Matthias Clasen  <mclasen@redhat.com>
 
+       * gdk/x11/gdkwindow-x11.[hc]: Keep a reference to the 
+       GdkCursor and add a private getter for it, so that we can 
+       update the cursor when the cursor theme changes.
+       
+       * gdk/gdk.symbols: 
+       * gdk/x11/gdkx.h: 
+       * gdk/x11/gdkcursor-x11.c (gdk_x11_display_set_cursor_theme): 
+       New function to change the cursor theme.
+
        * gdk/x11/gdkwindow-x11.c: Remove a lot of pointless
        g_return_if_fail() non-NULL checks.
 
index 5ffaa3982526053323e54cbe201a08d42f17d2fd..9fd51f2302d8f3db4b7e1ccc35c54e165dd9b9dd 100644 (file)
@@ -1,5 +1,14 @@
 2005-06-15  Matthias Clasen  <mclasen@redhat.com>
 
+       * gdk/x11/gdkwindow-x11.[hc]: Keep a reference to the 
+       GdkCursor and add a private getter for it, so that we can 
+       update the cursor when the cursor theme changes.
+       
+       * gdk/gdk.symbols: 
+       * gdk/x11/gdkx.h: 
+       * gdk/x11/gdkcursor-x11.c (gdk_x11_display_set_cursor_theme): 
+       New function to change the cursor theme.
+
        * gdk/x11/gdkwindow-x11.c: Remove a lot of pointless
        g_return_if_fail() non-NULL checks.
 
index 5ffaa3982526053323e54cbe201a08d42f17d2fd..9fd51f2302d8f3db4b7e1ccc35c54e165dd9b9dd 100644 (file)
@@ -1,5 +1,14 @@
 2005-06-15  Matthias Clasen  <mclasen@redhat.com>
 
+       * gdk/x11/gdkwindow-x11.[hc]: Keep a reference to the 
+       GdkCursor and add a private getter for it, so that we can 
+       update the cursor when the cursor theme changes.
+       
+       * gdk/gdk.symbols: 
+       * gdk/x11/gdkx.h: 
+       * gdk/x11/gdkcursor-x11.c (gdk_x11_display_set_cursor_theme): 
+       New function to change the cursor theme.
+
        * gdk/x11/gdkwindow-x11.c: Remove a lot of pointless
        g_return_if_fail() non-NULL checks.
 
index 0331e211d8c54becaa1370058c526e3ea488872a..b2434a900e9bca84cea43f86e2b3e787a98bd0be 100644 (file)
@@ -1262,6 +1262,7 @@ gdk_x11_cursor_get_xdisplay
 gdk_x11_display_get_xdisplay
 gdk_x11_display_grab
 gdk_x11_display_ungrab
+gdk_x11_display_set_cursor_theme
 gdk_x11_register_standard_event_type
 gdk_x11_drawable_get_xdisplay
 gdk_x11_drawable_get_xid
index 5f5b1c01614c145fdd94fbca9276b1f19868b24a..c5f5239887040195a86940cb14157a085a035776 100644 (file)
@@ -1111,6 +1111,7 @@ gdkx_colormap_get
 #if IN_FILE(__GDK_CURSOR_X11_C__)
 gdk_x11_cursor_get_xcursor
 gdk_x11_cursor_get_xdisplay
+gdk_x11_display_set_cursor_theme
 #endif
 
 #if IN_FILE(__GDK_DISPLAY_X11_C__)
index 3373ecdcfb4e9064bb21d5ec11d80b0258fd1540..69a2b49892549745894078bb2ab81e53fc33b7b3 100644 (file)
@@ -25,6 +25,9 @@
  */
 
 #include <config.h>
+
+#define GDK_PIXBUF_ENABLE_BACKEND
+
 #include <X11/Xlib.h>
 #include <X11/cursorfont.h>
 #ifdef HAVE_XCURSOR
@@ -40,7 +43,6 @@
 #include "gdkpixmap-x11.h"
 #include "gdkx.h"
 #include <gdk/gdkpixmap.h>
-#define GDK_PIXBUF_ENABLE_BACKEND
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include "gdkalias.h"
 
@@ -312,34 +314,6 @@ gdk_cursor_get_display (GdkCursor *cursor)
 
 #if defined(HAVE_XCURSOR) && defined(HAVE_XFIXES) && XFIXES_MAJOR >= 2
 
-#if 0
-XcursorComments *
-load_comments (const char       *file, 
-              const char       *theme)
-{
-    FILE           *f = 0;
-    XcursorImages   *images = 0;
-    XcursorComments *comments = 0;
-
-    if (theme)
-       f = XcursorScanTheme (theme, file);
-    if (!f)
-      f = XcursorScanTheme ("default", file);
-    if (f == XCURSOR_SCAN_CORE)
-      return 0;
-    if (f)
-      {
-       XcursorFileLoad (f, &comments, &images);
-       fclose (f);
-
-       if (images)
-         XcursorImagesDestroy (images);
-      }
-
-    return comments;
-}
-#endif
-
 /**
  * gdk_cursor_get_image:
  * @cursor: a #GdkCursor
@@ -361,14 +335,11 @@ gdk_cursor_get_image (GdkCursor *cursor)
   GdkCursorPrivate *private;
   XcursorImages *images = NULL;
   XcursorImage *image;
-  XcursorComments *comments;
-  Atom atom;
   gint size;
   gchar buf[32];
   guchar *data;
   GdkPixbuf *pixbuf;
   gchar *theme;
-  gint i, j;
   
   g_return_val_if_fail (cursor != NULL, NULL);
 
@@ -407,32 +378,95 @@ gdk_cursor_get_image (GdkCursor *cursor)
   g_snprintf (buf, 32, "%d", image->yhot);
   gdk_pixbuf_set_option (pixbuf, "y_hot", buf);
 
-#if 0
-  comments = load_comments (images->name, theme);
+  XcursorImagesDestroy (images);
+
+  return pixbuf;
+}
 
-  j = 0;
-  for (i = 0; i < comments->ncomment; i++)
+static void
+update_cursor (gpointer key,
+              gpointer value,
+              gpointer data)
+{
+  Display *xdisplay;
+  GdkWindow *window;
+  GdkCursor *cursor;
+  GdkCursorPrivate *private;
+  Cursor new_cursor = None;
+
+  if (!GDK_IS_WINDOW (value))
+    return;
+
+  cursor = _gdk_x11_window_get_cursor (GDK_WINDOW (value));
+
+  if (!cursor)
+    return;
+
+  private = (GdkCursorPrivate *) cursor;
+  xdisplay = (Display *)data;
+         
+  if (private->xcursor != None)
     {
-      switch (comments->comments[i].comment_type)
+      if (cursor->type == GDK_CURSOR_IS_PIXMAP)
        {
-       case XCURSOR_COMMENT_COPYRIGHT:
-         gdk_pixbuf_set_option (pixbuf, "copyright", comments->comments[i].comment);
-         break;
-       case XCURSOR_COMMENT_LICENSE:
-         gdk_pixbuf_set_option (pixbuf, "license", comments->comments[i].comment);
-         break;
-       default:
-         g_snprintf (buf, 32, "comment%d", j++);
-         gdk_pixbuf_set_option (pixbuf, buf, comments->comments[i].comment);
-         break;
+         if (private->name)
+           new_cursor = XcursorLibraryLoadCursor (xdisplay, private->name);
        }
+      else 
+       new_cursor = XcursorShapeLoadCursor (xdisplay, cursor->type);
+      
+      if (new_cursor != None)
+       XFixesChangeCursor (xdisplay, new_cursor, private->xcursor);
     }
-  XcursorCommentsDestroy (comments);
-#endif
+}
 
-  XcursorImagesDestroy (images);
+/**
+ * gdk_x11_display_set_cursor_theme:
+ * @display: a #GdkDisplay
+ * @theme: the name of the cursor theme to use
+ * @size: the cursor size to use
+ *
+ * Sets the cursor theme from which the images for cursor
+ * should be taken. 
+ * 
+ * If the windowing system supports it, existing cursors created 
+ * with gdk_cursor_new(), gdk_cursor_new_for_display() and 
+ * gdk_cursor_new_for_name() are updated to reflect the theme 
+ * change. Custom cursors constructed with gdk_cursor_new_from_pixmap() 
+ * or gdk_cursor_new_from_pixbuf() will have to be handled
+ * by the application (GTK+ applications can learn about 
+ * cursor theme changes by listening for change notification
+ * for the corresponding #GtkSetting).
+ *
+ * Since: 2.8
+ */
+void
+gdk_x11_display_set_cursor_theme (GdkDisplay  *display,
+                                 const gchar *theme,
+                                 const gint   size)
+{
+  GdkDisplayX11 *display_x11;
+  Display *xdisplay;
+  gchar *old_theme;
+  gint old_size;
 
-  return pixbuf;
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+
+  display_x11 = GDK_DISPLAY_X11 (display);
+  xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+  old_theme = XcursorGetTheme (xdisplay);
+  old_size = XcursorGetDefaultSize (xdisplay);
+
+  if (old_size == size && 
+      old_theme && strcmp (old_theme, theme) == 0)
+    return;
+
+  XcursorSetTheme (xdisplay, theme);
+  XcursorSetDefaultSize (xdisplay, size);
+    
+  g_hash_table_foreach (display_x11->xid_ht, 
+                       update_cursor, xdisplay);
 }
 
 #else
@@ -445,6 +479,16 @@ gdk_cursor_get_image (GdkCursor *cursor)
   return NULL;
 }
 
+void
+gdk_x11_display_set_cursor_theme (GdkDisplay  *display,
+                                 const gchar *theme,
+                                 const gint   size)
+{
+  g_return_if_fail (GDK_IS_DISPLAY (display));
+
+  /* nothing to do */
+}
+
 #endif
 
 #ifdef HAVE_XCURSOR
index a1b6c2c61e2153e53e06008dd3e826aa42ffbf3a..83082c02782895c6c962ed081cc616985ac46a23 100644 (file)
@@ -224,6 +224,9 @@ gdk_window_impl_x11_finalize (GObject *object)
   if (window_impl->toplevel)
     g_free (window_impl->toplevel);
 
+  if (window_impl->cursor)
+    gdk_cursor_unref (window_impl->cursor);
+
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -2854,22 +2857,51 @@ void
 gdk_window_set_cursor (GdkWindow *window,
                       GdkCursor *cursor)
 {
+  GdkWindowObject *private;
+  GdkWindowImplX11 *impl;
   GdkCursorPrivate *cursor_private;
   Cursor xcursor;
   
   g_return_if_fail (GDK_IS_WINDOW (window));
     
+  private = (GdkWindowObject *)window;
+  impl = GDK_WINDOW_IMPL_X11 (private->impl);
   cursor_private = (GdkCursorPrivate*) cursor;
 
+  if (impl->cursor)
+    {
+      gdk_cursor_unref (impl->cursor);
+      impl->cursor = NULL;
+    }
+
   if (!cursor)
     xcursor = None;
   else
     xcursor = cursor_private->xcursor;
   
   if (!GDK_WINDOW_DESTROYED (window))
-    XDefineCursor (GDK_WINDOW_XDISPLAY (window),
-                  GDK_WINDOW_XID (window),
-                  xcursor);
+    {
+      XDefineCursor (GDK_WINDOW_XDISPLAY (window),
+                    GDK_WINDOW_XID (window),
+                    xcursor);
+      
+      if (cursor)
+       impl->cursor = gdk_cursor_ref (cursor);
+    }
+}
+
+GdkCursor *
+_gdk_x11_window_get_cursor (GdkWindow *window)
+{
+  GdkWindowObject *private;
+  GdkWindowImplX11 *impl;
+  
+  g_return_if_fail (GDK_IS_WINDOW (window));
+    
+  private = (GdkWindowObject *)window;
+  impl = GDK_WINDOW_IMPL_X11 (private->impl);
+
+  return impl->cursor;
 }
 
 /**
index f95505aaff5dc535bf421a0a3c8812e10a652410..63e721e4e26f97daf52ec47bc9767309a13bd7b0 100644 (file)
@@ -75,6 +75,7 @@ struct _GdkWindowImplX11
   
   GdkXPositionInfo position_info;
   GdkToplevelX11 *toplevel;    /* Toplevel-specific information */
+  GdkCursor *cursor;
   gint8 toplevel_window_type;
   guint override_redirect : 1;
   guint use_synchronized_configure : 1;
@@ -158,6 +159,8 @@ void            _gdk_x11_window_tmp_reset_bg  (GdkWindow *window,
                                               gboolean   recurse);
 
 
+GdkCursor      *_gdk_x11_window_get_cursor    (GdkWindow *window);
+
 G_END_DECLS
 
 #endif /* __GDK_WINDOW_X11_H__ */
index 2e933b7069286ac28a8de35d7135e2190a096fa1..ac6ee4442116f76c17b91f989f011c795c729aae 100644 (file)
@@ -141,6 +141,10 @@ gpointer      gdk_xid_table_lookup_for_display (GdkDisplay *display,
 guint32       gdk_x11_get_server_time  (GdkWindow       *window);
 guint32       gdk_x11_display_get_user_time (GdkDisplay *display);
 
+void          gdk_x11_display_set_cursor_theme (GdkDisplay  *display,
+                                               const gchar *theme,
+                                               const gint   size);
+
 /* returns TRUE if we support the given WM spec feature */
 gboolean gdk_x11_screen_supports_net_wm_hint (GdkScreen *screen,
                                              GdkAtom    property);